﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace PuzzleCoop
{
    public abstract class GameObject
    {
        public PlayScreen playScreen;
        public Texture2D sprite;
        public Vector2 origin;
        public float scale;
        public Rectangle sourceRectangle;
        public bool alive;
        public Vector2 drawPosition;
        private Vector2 _position;
        public Vector2 position { set { prevPosition = _position; _position = value; } get { return _position; } }
        public Vector2 prevPosition;
        public Vector2 direction;
        public float rotation { get { return (float)Math.Atan2(direction.Y, direction.X); } }
        public float radius { get { return Math.Max(sourceRectangle.Width, sourceRectangle.Height) / 2; } }

        public GameObject(PlayScreen playScreen, Texture2D sprite)
        {
            this.playScreen = playScreen;
            this.sprite = sprite;
            direction = Direction.Right;
            position = drawPosition = Vector2.Zero;
            alive = true;
            scale = 1.0f;
            sourceRectangle = new Rectangle(0, 0, sprite.Width, sprite.Height);
            origin = new Vector2(sourceRectangle.Width / 2, sourceRectangle.Height / 2);
        }
            
        public abstract void Update(GameTime gameTime);

        public virtual void Draw(SpriteBatch spriteBatch)
        {
            if (alive)
            {
                if (!(this is Player)) drawPosition = position - playScreen.player.position + playScreen.player.drawPosition;
                //if (drawPosition.X < 1280 / 2 - origin.X) 
                spriteBatch.Draw(sprite, drawPosition, sourceRectangle, Color.White, rotation, origin, scale, SpriteEffects.None, 0);
            }
        }

        public virtual bool Collision(GameObject target)
        {
            return Vector2.Distance(this.position, target.position) < (this.radius + target.radius);
        }
            
        public virtual void MapCollision(Vector2 dir)
        {
            if (dir == Vector2.Zero) return;
            //alive = false;
            if (dir == Direction.Up || dir == Direction.Down)
                _position.Y = prevPosition.Y;
            if (dir == Direction.Left || dir == Direction.Right)
                _position.X = prevPosition.X;
        }

        public bool CheckCollisionWithBoard()
        {
            // Checa se está dentro dos limites do mapa
            if (position.X < 0 || position.Y < 0 || position.X >= Board.Size.X * Slot.SizeA || position.Y >= Board.Size.Y * Slot.SizeA) return true;

            // Pega o Slot atual
            Slot slot = playScreen.board.GetSlot(position);
            if (slot == null) return true; // se for null é pq está fora dos limites do mapa
            if (!(slot is Block)) return true; // só pode se movimentar em um bloco
            return (slot as Block).CollidesWith(this);
        }
    }
}